


#include "token_bucket.h"
#include "qelib.h"



static void *thread_refill_tokens(void *ref)
{
    fix_speed_token *token = (fix_speed_token *)ref;

    while (1) {

        pthread_mutex_lock(&token->lock);

        if (token->tokens < token->max) {
            token->tokens += token->rate;
            if (token->tokens > token->max)
                token->tokens = token->max;
            //printf("token %d\n", token->tokens);
        }

        pthread_mutex_unlock(&token->lock);

        qe_msleep(1000);
    }

    return QE_NULL;
}

fix_speed_token *fix_speed_token_new(qe_u32 init, qe_u32 max, qe_u32 rate)
{
    fix_speed_token *token = qe_malloc(sizeof(fix_speed_token));
    qe_assert(token != QE_NULL);

    token->max   = max;
    token->rate  = rate;
    token->tokens = init;

    pthread_mutex_init(&token->lock, QE_NULL);

    pthread_create(&token->thread, NULL, thread_refill_tokens, token);
    
    return token;
}

void fix_speed_token_set(fix_speed_token *token, qe_u32 init, qe_u32 max, qe_u32 rate)
{
    token->max   = max;
    token->rate  = rate;
    token->tokens = init;

    pthread_mutex_init(&token->lock, QE_NULL);
}

void fix_speed_token_run(fix_speed_token *token)
{
    pthread_create(&token->thread, NULL, thread_refill_tokens, token);
}

qe_bool fix_speed_token_get(fix_speed_token *token, int size)
{
    qe_bool has_token = qe_false;

    pthread_mutex_lock(&token->lock);

    if (token->tokens > size) {
        token->tokens -= size;
        has_token = qe_true;
        //printf("get token %d\n", token->tokens);
    }

    pthread_mutex_unlock(&token->lock);

    return has_token;
}


